package com.essence.grabiec104.grab.executor.handler;

import com.essence.common.model.BytesFrame;
import com.essence.common.model.EnumTypeAdapter;
import com.essence.common.model.Packet;
import com.essence.grabiec104.grab.model.YKComparison;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class YKFrameComparisonHandler extends AbstractSocketFrameHandler {
    @Override
    protected boolean doHandle(BytesFrame frame) {
        Packet pkt = frame.getPacket();
        String host = "";
        if (frame.getDirection() == BytesFrame.DirectionEnum.Upstream) {
            host = frame.getSrcHost();
        }
        if (frame.getDirection() == BytesFrame.DirectionEnum.Downstream) {
            host = frame.getDstHost();
        }
        if (pkt.getPacketType() != Packet.PacketEnum.I) {
            return false;
        }
        List<YKComparison.YKComparisonItem> items = new ArrayList<>();
        if (pkt.getTieIdentification().getValue() == 45
                || pkt.getTieIdentification().getValue() == 46
                || pkt.getTieIdentification().getValue() == 58
                || pkt.getTieIdentification().getValue() == 59) {
            YKComparison.YKComparisonItem item = new YKComparison.YKComparisonItem();
            int asduAddr = pkt.getAsduAddressInt();
            item.setCommonAddress(asduAddr);
            item.setTimestamp(frame.getTimestamp());
            item.setTieIdentification(pkt.getTieIdentification().getDescription());
            item.setTieIdentificationIndex(pkt.getTieIdentification().getValue());
            item.setCause(pkt.getCot().getCause().getDescription());
            item.setCauseIndex(pkt.getCot().getCause().getCode());
            if (!pkt.getDigitalSignals().isEmpty()) {
                Packet.DigitalSignals ds = pkt.getDigitalSignals().get(0);
                item.setPointAddress(ds.getInfoAdr());
                item.setValue(ds.getSpi());
                item.setIv(ds.getIv());
                item.setDirection(frame.getDirection() == BytesFrame.DirectionEnum.Upstream ? 0 : 1);
            }
            items.add(item);
            YKComparison ykComparison = new YKComparison();
            ykComparison.getItemsGroupBy().put(host, items);

            Gson gson = new GsonBuilder()
                    .registerTypeAdapterFactory(new TypeAdapterFactory() {
                        @Override
                        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
                            Class<? super T> rawType = type.getRawType();
                            if (!Enum.class.isAssignableFrom(rawType)) {
                                return null;
                            }
                            TypeAdapter<T> adapter = new EnumTypeAdapter();
                            return adapter;
                        }
                    })
                    .create();
            String response = gson.toJson(ykComparison);
            log.info("ykComparison: {}", response);
            publish("yk-comparison-publish", response);
            return true;
        }
        return false;
    }

    @Override
    public String getName() {
        return "YKFrameComparisonHandler";
    }
}
